package com.yy.filters;


import cn.hutool.json.JSONUtil;
import com.yy.config.PathWhiteListProperties;
import com.yy.constant.UserConstant;
import com.yy.model.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.RequestPath;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 全局过滤器
 */
@Component
@RequiredArgsConstructor
public class GlobalFilter implements org.springframework.cloud.gateway.filter.GlobalFilter, Ordered {

    private final PathWhiteListProperties pathWhiteListProperties;

    private final AntPathMatcher pathMatcher = new AntPathMatcher();
    private final RedisTemplate<String, Object> redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 处理全局所有的请求  登录校验
        //如果是登录注册请求 直接放行
        RequestPath requestPath = exchange.getRequest().getPath();
        if (isAuth(requestPath)) {
            //放行
            return chain.filter(exchange);
        }
        System.out.println("拦截器启动!");
        //其他请求  校验用户是否登录
        //1.从 redis 获取用户信息
        String sessionId = exchange.getRequest().getHeaders().get(UserConstant.USER_Seession_ID).get(0);
        String jsonStr = (String) redisTemplate.opsForValue().get(UserConstant.USER_LOGIN_STATE + sessionId);
        try {
            User currentUser = JSONUtil.toBean(jsonStr, User.class);
            if (currentUser == null || currentUser.getId() == null) {
                //如果用户信息不存在  拒绝请求
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
            //对下游的请求头修改 把用户信息放入请求头
            exchange.getRequest().mutate().header(UserConstant.USER_Seession_ID, sessionId);
        } catch (Exception e) {
            //如果用户信息不存在  拒绝请求
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        //2.放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    boolean isAuth(RequestPath requestPath) {
        String path = requestPath.value();
        List<String> exclude = pathWhiteListProperties.getExclude();
        for (String excludePath : exclude) {
            if (pathMatcher.match(excludePath, path)) {
                return true;
            }
        }
        return false;
    }
}
